/**********************************************************************//**
 * @file table_utils.c
 * @brief function summary
 *
 * Development Div. : PI&S SSE SYS1-3
 * Author : Yoichiro SATO\n
 * Copyright 2011 Sony Corporation. \n
 * ================================================================== */
/**********************************************************************/

/* --- include files ------------------------------------------------ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "hsv.h"
#include "../common.h"

/* --- macro definitions -------------------------------------------- */
//#define N 3
#define N 6
/* --- structure/class definitions ---------------------------------- */
/* --- function prototypes ------------------------------------------ */
/* --- static values ------------------------------------------------ */
int g_p_points[N][2] = {
    //  s,   v
#if 1
    {0,   0},
    {18,  24},
    {40,  36},
    {100, 80},
    {120, 140},
    {127, 255},
#if 0
    // pattern 0-0
    {   0,   0 },
    { 128,  32 },
    { 128, 128 },
    { 128, 255 },
    // pattern 0-1
    {   0,   0 },
    {  32,  32 },
    { 128, 128 },
    { 128, 255 },
    // pattern 0-2
    {   0,   0 },
    {  64,  32 },
    { 128, 128 },
    { 128, 255 },
    // pattern 0-3
    {   0,   0 },
    {  96,  32 },
    { 128, 128 },
    { 128, 255 },

    // pattern 1-0
    {   0,   0 },
    { 128,  64 },
    { 128, 128 },
    { 128, 255 },
    // pattern 1-1
    {   0,   0 },
    {  32,  64 },
    { 128, 128 },
    { 128, 255 },
    // pattern 1-2
    {   0,   0 },
    {  64,  64 },
    { 128, 128 },
    { 128, 255 },
    // pattern 1-3
    {   0,   0 },
    {  96,  64 },
    { 128, 128 },
    { 128, 255 },
#endif
#else
#if 1 /* cone */
    {   0,   0 },
    {  64, 128 },
    { 128, 255 },
#else /* column */
    {   0,   0 },
    { 128,   1 },
    { 128, 255 },
#endif
#endif
};

/* --- auto values -------------------------------------------------- */


/* ------------------------------------------------------------------ *//**
 * @brief function summary
 * @param argument1 [in] explanation
 * @param argument2 [out] explanation
 * @retval 0 no error
 * @retval 1 error
 */
/* ------------------------------------------------------------------ */
int exec_create_saturation_table(int *p_table, char *p_filename, char *p_bin_name)
{
    int i, v;
    float a, b;
    float p1[2], p2[2];
    FILE *fp;
    float p_ftable[256];
    unsigned short p_stable[256];
    
    if (p_filename) {
        fp = fopen(p_filename, "wt");
    }
    
    for (i=0; i<N-1; i++) {
        
        p1[0] = (float)g_p_points[i][0];
        p1[1] = (float)g_p_points[i][1];
        
        p2[0] = (float)g_p_points[i+1][0];
        p2[1] = (float)g_p_points[i+1][1];
        
        if ((p2[0] - p1[0]) == 0.0f) {
            a = 1.0f;
        } else {
            a = (p2[1] - p1[1])/(p2[0] - p1[0]);
        }
        
        if ((p1[0] - p2[0]) == 0.0f) {
            
            for (v=(int)p1[1]; v<=(int)p2[1]; v++) {
                
                if (v) {
                    p_ftable[v] = p2[0];
                    p_table[v]  = (int)((p_ftable[v]/(float)v)*(float)SHIFT16_MULTI + 0.5f);
                } else {
                    p_ftable[v] = 0.0f;
                    p_table[v] = 0;
                }
            }
            
        } else {
            
            b = (p2[1]*p1[0] - p1[1]*p2[0])/(p1[0] - p2[0]);
            
            for (v=(int)p1[1]; v<=(int)p2[1]; v++) {
                if (v) {
                    p_ftable[v] = (((float)v - b)/a);
                    p_table[v]  = (int)((p_ftable[v]/(float)v)*(float)SHIFT12_MULTI + 0.5f);
                } else {
                    p_ftable[v] = 0.0f;
                    p_table[v] = 0;
                }
            }
        }
    }
    
    if (fp) {
        
        fprintf(fp, "unsigned short g_p_saturation_table[256] = {\n");
        
        for (v=0; v<256; v++) {
            fprintf(fp, "\t%d,\t//%lf\n", p_table[v], p_ftable[v]);
        }
        fprintf(fp, "};\n");
        fclose(fp);
    }
    
    if (p_bin_name) {
        
        fp = fopen(p_bin_name, "wb");
        for (v=0; v<256; v++) {
            p_stable[v] = p_table[v];
        }
        fwrite(p_stable, sizeof(short), 256, fp);
        
        fclose(fp);
    }
    
    return 0;
}

/* ------------------------------------------------------------------ *//**
 * @brief function summary
 * @param argument1 [in] explanation
 * @param argument2 [out] explanation
 * @retval 0 no error
 * @retval 1 error
 */
/* ------------------------------------------------------------------ */
int exec_create_hsv_coef_inv_table(int n, float *p_hsv_coef_inv, char *p_filename)
{
    int i;
    FILE *fp;
    
    p_hsv_coef_inv[0] = 0.0f;
    
    for (i=1; i<n; i++) {
        p_hsv_coef_inv[i] = 1.0f/(float)i;
    }
    
    if (p_filename) {
        
        fp = fopen(p_filename, "wt");
        
        if (fp) {
            fprintf(fp, "int g_p_hsv_coef_inv[%d] = {\n", n);
            for (i=0; i<n; i++) {
                fprintf(fp, "\t%d,\t// %d\n", (int)(p_hsv_coef_inv[i]*(float)SHIFT16_MULTI + 0.5f), i);
            }
            fprintf(fp, "};\n\n");
            
            fprintf(fp, "float g_p_hsv_fcoef_inv[%d] = {\n", n);
            for (i=0; i<n; i++) {
                fprintf(fp, "\t%lff,\n", p_hsv_coef_inv[i]);
            }
            fprintf(fp, "};");
            fclose(fp);
        }
    }
    return 0;
}

/* ------------------------------------------------------------------ *//**
 * @brief function summary
 * @param argument1 [in] explanation
 * @param argument2 [out] explanation
 * @retval 0 no error
 * @retval 1 error
 */
/* ------------------------------------------------------------------ */
int exec_create_sincos_table(char *p_filename)
{
    int i, n = 360;
    FILE *fp;
    double pi = 3.1415926535897932384626433832795;
    
    if (p_filename) {
        
        fp = fopen(p_filename, "wt");
        
        if (fp) {
            fprintf(fp, "float g_p_sin_table[%d] = {\n", n);
            for (i=0; i<n; i++) {
                fprintf(fp, "\t%lff,\n", (float)sin(pi*(double)i/180.0));
            }
            fprintf(fp, "};\n\n");
            
            fprintf(fp, "float g_p_cos_ftable[%d] = {\n", n);
            for (i=0; i<n; i++) {
                fprintf(fp, "\t%lff,\n", (float)cos(pi*(double)i/180.0));
            }
            fprintf(fp, "};\n\n");
            
            fprintf(fp, "short g_p_cos_table[%d] = {\n", n);
            for (i=0; i<n; i++) {
                fprintf(fp, "\t%d,\n", (int)((float)cos(pi*(double)i/180.0)*(float)SHIFT14_MULTI + 0.5f));
            }
            fprintf(fp, "};");
            fclose(fp);
        }
    }
    return 0;
}
